<?php

declare(strict_types=1);

namespace app\common\lib;

/**
 * 严格模式下针对string字符串操作的基础类库
 * Class Str
 * @package app\common\lib
 */
class Str
{

    /**
     * 获取用户密码
     * @param string $password
     * @return string
     */
    public static function getUserPassword(string $password): string
    {
        return md5($password . '_df');
    }

    /**
     * 密码复杂度验证
     * 规则：6-20位，包含大小写、数字、特殊字符，且不能包含常用密码
     * @param $password
     * @return array
     */
    public static function checkUserPassword($password){
        $result = [
            'res'=>false,
            'msg'=>'密码必须包含大小字母、小写字母、数字以及特殊字符(~!@#$%^&*()_+=?)'
        ];

        //长度验证
        if(!preg_match('/.{6,20}/',$password)){
            $result['msg'] = '密码长度不符合要求(6-20位)';
            return $result;
        }

        //复杂度验证
        $score = 0;
        //验证是否包含数字
        if(preg_match('/[0-9]+/',$password)){
            $score++;
        }
        //验证是否包含小写字母
        if(preg_match('/[a-z]+/',$password)){
            $score++;
        }
        //验证是否包含大写字母
        if(preg_match('/[A-Z]+/',$password)){
            $score++;
        }
        //验证是否包含特殊字符
        if(preg_match('/[~!@#$%^&*()_+=?]+/',$password)){
            $score++;
        }
        if($score < 4){
            return $result;
        }

        $result = [
            'res' => true,
            'msg'=>'密码复杂度符合要求'
        ];
        return $result;
    }

    /**
     * 生成登录所需的token
     * @param $string
     * @return string
     */
    public static function getLoginToken($string)
    {
        //生成token
        $str = md5(uniqid(md5(microtime(false)), false));//生成一个不会重复的字符串
        $token = sha1($str . $string);
        return $token;
    }

    /**
     * 过滤微信昵称特殊符号
     * @param $str
     * @return string|string[]|null
     */
    public static function filterEmoji($str)
    {
        $str = preg_replace_callback(    //执行一个正则表达式搜索并且使用一个回调进行替换
            '/./u',
            function (array $match) {
                return strlen($match[0]) >= 4 ? '' : $match[0];
            },
            $str);
        return $str;
    }

    /**
     * 18位身份证校验码有效性检查
     * @param $idcard
     * @return bool
     */
    public static function idcardCheck($idcard){
        if (strlen($idcard) != 18){ return false; }
        $idcard_base = substr($idcard, 0, 17);
        if (self::idcardVerifyNumber($idcard_base) != strtoupper(substr($idcard, 17, 1))){
            return false;
        }else{
            return true;
        }
    }
    // 计算身份证校验码，根据国家标准GB 11643-1999
    public static function idcardVerifyNumber($idcard_base) {
        if(strlen($idcard_base) != 17) {
            return false;
        }
        //加权因子
        $factor = array(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2);
        //校验码对应值
        $verify_number_list = array('1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2');
        $checksum = 0;
        for ($i = 0; $i < strlen($idcard_base); $i++) {
            $checksum += substr($idcard_base, $i, 1) * $factor[$i];
        }
        $mod = $checksum % 11;
        $verify_number = $verify_number_list[$mod];
        return $verify_number;
    }

    //通过身份证号获取性别
    public static function getSexByIdCard($id_card){
        $sex = substr($id_card, (strlen($id_card)==18 ? -2 : -1), 1) % 2 ? '1' : '2';
        return $sex;
    }

    //姓名等字符串隐私处理
    public static function dealSecretString($value){
        $first = mb_substr($value,0,1);

        $starWord = '';
        $str_len = mb_strlen($value);
        for ($i=0;$i<$str_len-1;$i++){//减去第一个字
            $starWord.='*';
        }

        $result = $first.$starWord;
        return $result;
    }

    //去除标签、图像等 仅保留文本
    public static function strip_html_tags($content)
    {
        $search = array("'<script[^>]*?>.*?</script>'si",  // 去掉 javascript
            "'<[\/\!]*?[^<>]*?>'si",           // 去掉 HTML 标记
            "'([\r\n])[\s]+'",                 // 去掉空白字符
            "'&(quot|#34);'i",                 // 替换 HTML 实体
            "'&(amp|#38);'i",
            "'&(lt|#60);'i",
            "'&(gt|#62);'i",
            "'&(nbsp|#160);'i",
            "'&(iexcl|#161);'i",
            "'&(cent|#162);'i",
            "'&(pound|#163);'i",
            "'&(copy|#169);'i",
            "'&ldquo;'i",
            "'&rdquo;'i"
        );

        $replace = array("",
            "",
            "\\1",
            "\"",
            "&",
            "<",
            ">",
            " ",
            chr(161),
            chr(162),
            chr(163),
            chr(169),
            "‘",
            "’"
        );
        $matches = "\\1";
        $filterHtml = preg_replace($search, $replace, $content, -1);
        $filterHtml = preg_replace_callback("'&#(\d+);'", function($matches){
            return chr($matches[1]);
        }, $filterHtml, -1);
        return $filterHtml;
    }

    //java集合对象转php可用的数组
    public static function object2array(&$object){
        $object = json_decode(json_encode($object),true);
        return $object;
    }

    public static function globalRequestDomain(){
        $domain = str_replace('http://','https://',request()->domain());
        //$domain = request()->domain();
        return $domain;
    }
}
